using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;

namespace HunterPluginSDK
{
    public class PluginsFactory
    {
        public List<Interface.IHunterPlugin> PluginsList;
        private Interface.IProgressHandler _progressHandler;

        private PluginsFactory()
        {
            PluginsList = new List<HunterPluginSDK.Interface.IHunterPlugin>();
        }

        static private PluginsFactory _instance;
        static public PluginsFactory Instance
        {
            get {
                if (_instance == null)
                    _instance = new PluginsFactory();
                return _instance; 
            }
        }

        public List<Interface.IHunterPlugin> ReadPlugins(string pluginDirectory, Interface.IProgressHandler ph)
        {
            _progressHandler = ph;
            PluginsList.Clear();
            DirectoryInfo dirInfo = new DirectoryInfo(pluginDirectory);
            if (!dirInfo.Exists)
            {
                _progressHandler.WriteToOutput("PlugIn directory not exists", LogPriority.WARNING);
            }
            else
            {
                foreach (FileInfo fileCheck in dirInfo.GetFiles())
                {
                    if (fileCheck.Extension == Constants.PlugInExt)
                    {
                        Assembly pluginAssembly = Assembly.LoadFrom(fileCheck.FullName);
                        if (pluginAssembly != null)
                        {
                            foreach (Type pluginType in pluginAssembly.GetTypes())
                            {
                                if (pluginType.IsPublic && !pluginType.IsAbstract)
                                {
                                    Type typeInterface = pluginType.GetInterface("HunterPluginSDK.Interface.IHunterPlugin");
                                    if (typeInterface != null)
                                    {
                                        Interface.IHunterPlugin pluginCreator =
                                            (Interface.IHunterPlugin)Activator.CreateInstance(pluginType);

                                        if (pluginCreator != null)
                                        {
                                            if (pluginCreator.Load(ph))
                                            {
                                                PluginsList.Add(pluginCreator);
                                                this._progressHandler.WriteToOutput("Plugin " + pluginCreator.PluginName + " loaded successfuly", LogPriority.INFO);
                                            }
                                            else if(pluginCreator.Enabled)
                                            {
                                                this._progressHandler.WriteToOutput("Plugin " + pluginCreator.PluginName + " could not be loaded", LogPriority.ERROR);
                                            }
                                            //if (IsPluginEnabled(pluginCreator.SupportedSystem, enabledSystems))
                                            {

                                                AssemblyDescriptionAttribute attrDescInfo =
                                                    (AssemblyDescriptionAttribute)AssemblyDescriptionAttribute.GetCustomAttribute(pluginAssembly, typeof(AssemblyDescriptionAttribute));

                                                AssemblyCopyrightAttribute attrCompInfo =
                                                    (AssemblyCopyrightAttribute)AssemblyCopyrightAttribute.GetCustomAttribute(pluginAssembly, typeof(AssemblyCopyrightAttribute));

                                                //installedPlugins.Add(attrDescInfo.Description + "," + pluginAssembly.FullName + "\r\n" + attrCompInfo.Copyright);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }
	
    }
}
